package com.transformer.shobal.activitys.media;

import android.media.MediaRecorder;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import com.transformer.shobal.R;
import com.transformer.shobal.activitys.BaseActivity;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

/**
 * Created by Administrator on 2015/4/8.
 */
public class MediaTestActivity extends BaseActivity implements SurfaceHolder.Callback,MediaRecorder.OnErrorListener,MediaRecorder.OnInfoListener{
    private static final int mVideoEncoder = MediaRecorder.VideoEncoder.H264;
    private LocalSocket receiver, sender;
    private LocalServerSocket lss;
    private MediaRecorder mMediaRecorder = null;
    private boolean mMediaRecorderRecording = false;
    private SurfaceView mSurfaceView = null;
    private SurfaceHolder mSurfaceHolder = null;
    private Thread thread;
    private Button btnStart,btnStop;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.media_layout);
        init();
    }

    private void init(){
        mSurfaceView = (SurfaceView) findViewById(R.id.video_surface);
        SurfaceHolder holder = mSurfaceView.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        //media

        btnStart = (Button) findViewById(R.id.start_media);
        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openSocket();
                initializeVideo();
                startVideoRecording();
            }
        });

        btnStop = (Button) findViewById(R.id.stop_media);
        btnStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mMediaRecorderRecording){
                    releaseMediaRecorder();
                    closeSocket();
                }
            }
        });
    }

    public static void printHexString( byte[] b) {
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            System.out.print(hex.toUpperCase() );
        }

    }

    private boolean initializeVideo() {
        System.out.println("initializeVideo");
        if (mSurfaceHolder == null)
            return false;
        if( mMediaRecorderRecording)
            return true;
        mMediaRecorderRecording = true;
        if (mMediaRecorder == null)
            mMediaRecorder = new MediaRecorder();
        else
            mMediaRecorder.reset();
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setVideoFrameRate(30);
        mMediaRecorder.setVideoSize(352, 288);
        mMediaRecorder.setVideoEncoder(mVideoEncoder);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
        mMediaRecorder.setMaxDuration(0);
        mMediaRecorder.setMaxFileSize(0);
        mMediaRecorder.setOutputFile(sender.getFileDescriptor());
        try {
            mMediaRecorder.setOnInfoListener(this);
            mMediaRecorder.setOnErrorListener(this);
            mMediaRecorder.prepare();
            mMediaRecorder.start();
        } catch (IOException exception) {
            releaseMediaRecorder();
            finish();
            return false;
        }
        return true;
    }

    private void releaseMediaRecorder() {
        System.out.println("Releasing media recorder.");
        if (mMediaRecorder != null) {
            if (mMediaRecorderRecording) {
                try {
                    mMediaRecorder.setOnErrorListener(null);
                    mMediaRecorder.setOnInfoListener(null);
                    mMediaRecorder.stop();
                } catch (RuntimeException e) {
                    System.out.println("stop fail: " + e.getMessage());
                }
                mMediaRecorderRecording = false;
            }
            mMediaRecorder.reset();
            mMediaRecorder.release();
            mMediaRecorder = null;
        }
    }

    private void openSocket(){
        //receiver
/*        if(receiver !=null && !receiver.isClosed())
            return;*/
        if(mMediaRecorderRecording)
            return;

        receiver = new LocalSocket();
        try {
            lss = new LocalServerSocket("VideoCamera");
            receiver.connect(new LocalSocketAddress("VideoCamera"));
            receiver.setReceiveBufferSize(500000);
            receiver.setSendBufferSize(500000);
            sender = lss.accept();
            sender.setReceiveBufferSize(500000);
            sender.setSendBufferSize(500000);
        } catch (Exception e) {
            finish();
            return;
        }
    }

    private void closeSocket(){
        try {
            if(lss!=null){
                lss.close();
            }

            if(receiver!=null && receiver.isConnected()){
                receiver.close();
            }

            if(sender!=null && sender.isConnected()){
                sender.close();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private void startVideoRecording() {
        (thread = new Thread() {
            @Override
            public void run() {
                    int frame_size = 20000;
                    byte[] buffer = new byte[1024 * 10];
                    int num=0, number = 0;
                    InputStream fis = null;
                    File videoF=new File(Environment.getExternalStorageDirectory()+"/my1.mp4");
                    if(videoF.exists()){
                        videoF.delete();
                    }
                    try {
                        videoF.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    FileOutputStream fos = null;
                    try {
                        fos= new FileOutputStream(videoF);
                        fis = receiver.getInputStream();
                    } catch (IOException e1) {
                        return;
                    }


                    while (true) {
                        try {
/*                            System.out.println("start read-------------");
                            int firstChar = fis.read();
                            if(firstChar == -1){
                                System.out.println("---------num=-1");
                                break;
                            }
                            buffer[0] = (byte)firstChar;
                            if(buffer.length >= fis.available()+1){
                                num = fis.read(buffer,1,fis.available());
                            }else{
                                num = fis.read(buffer,1,buffer.length-1);
                            }
                            fos.write(buffer,0,num);
                            System.out.println("ok-----------number="+number+",num="+num);
                            System.out.println("buffer="+ Arrays.toString(buffer));
                            number += num;*/
/*                            if(!mMediaRecorderRecording){
                                System.out.println("end--------------"+number);
                                fis.close();
                                fos.close();
                                closeSocket();
                                break;
                            }*/

                            System.out.println("read video---------------");
                            num = fis.read(buffer);
                            if(num <= 0){
                                System.out.println("-----num="+num);
                                continue;
                            }
                            fos.write(buffer,0,num);
                            System.out.println("ok-----------number="+number+",num="+num);
                            System.out.println("buffer="+ Arrays.toString(buffer));
                            number += num;

                        } catch (IOException e) {
                            try {
                                fis.close();
                                fos.close();
                            } catch (IOException e1) {
                                e1.printStackTrace();
                            }
                            System.out.println("exception break error ="+e.getMessage()+",,,num="+num+",------buff="+Arrays.toString(buffer));
                            break;
                        } catch (IndexOutOfBoundsException e){
                            System.out.println("exception IndexOutOfBoundsException");
                            break;
                        }
                  }
                System.out.print("thread stop-------------");
            }
        }).start();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        System.out.println("surfaceCreated");
        mSurfaceHolder = holder;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        System.out.println("surfaceChanged");
        mSurfaceHolder = holder;
        if (!mMediaRecorderRecording) {
//            initializeVideo();
//            startVideoRecording();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        System.out.println("surfaceDestroyed");
        mSurfaceView = null;
        mSurfaceHolder = null;
        mMediaRecorder = null;
        if (thread != null) {
            thread.interrupt();
        }
    }

    @Override
    public void onError(MediaRecorder mr, int what, int extra) {
        if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
            System.out.println("MEDIA_RECORDER_ERROR_UNKNOWN");
            finish();
        }
    }

    @Override
    public void onInfo(MediaRecorder mr, int what, int extra) {
        switch (what) {
            case MediaRecorder.MEDIA_RECORDER_INFO_UNKNOWN:
                System.out.println("MEDIA_RECORDER_INFO_UNKNOWN");
                break;
            case MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED:
                System.out.println("MEDIA_RECORDER_INFO_MAX_DURATION_REACHED");
                break;
            case MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED:
                System.out.println("MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED");
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        releaseMediaRecorder();
        closeSocket();
        Log.i("shobal",this.getLocalClassName()+"onDestroy");
    }
}